package cn.kgc.api.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.kgc.api.entity.Menus;
import cn.kgc.api.entity.Roles;
import cn.kgc.api.form.RolesAddForm;
import cn.kgc.api.form.RolesUpdateForm;
import cn.kgc.api.service.MenusService;
import cn.kgc.api.service.RolesService;
import cn.kgc.common.constant.ResultConstant;
import cn.kgc.common.util.HttpException;
import cn.kgc.common.vo.Pager;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import lombok.extern.slf4j.Slf4j;

/**
 * @author kgc
 */
@RestController
@RequestMapping("/roles")
@Api(tags = "角色管理模块")
@Validated
@Slf4j
@CrossOrigin
public class RolesController {
    @Resource
    private RolesService rolesService;

    @Resource
    private MenusService menusService;

    @GetMapping("/list")
    @ApiOperation(value = "查询角色列表")
    public List<Roles> getRolesList() {
        return rolesService.list();
    }

    @PostMapping("/page")
    @ApiOperation(value = "分页查询角色列表")
    public Pager<Roles> page(@RequestBody Map<String, Object> maps) {
        String roleName = MapUtil.getStr(maps, "roleName");
        int currentPage = MapUtil.getInt(maps, "currentPage", 1);
        int pageSize = MapUtil.getInt(maps, "pageSize", 5);

        Page<Roles> page = new Page<>(currentPage, pageSize);
        LambdaQueryWrapper<Roles> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.likeRight(StrUtil.isNotBlank(roleName), Roles::getRoleName, roleName);
        rolesService.page(page, queryWrapper);

        return Pager.build(page);
        //String roleName2 = Optional.ofNullable(maps.get("roleName")).orElse("").toString();
    }

    @PostMapping("/save")
    @ApiOperation(value = "新增角色")
    public boolean save(@RequestBody RolesAddForm rolesAddForm) {
        checkRoleNameIsBlank(rolesAddForm.getRoleName());
        checkRoleNameRepeat(rolesAddForm.getRoleName());
        Roles roles = new Roles();
        BeanUtil.copyProperties(rolesAddForm, roles);
        return rolesService.save(roles);
    }

    @PostMapping("/update")
    @ApiOperation(value = "更新角色信息")
    public boolean update(@RequestBody RolesUpdateForm rolesUpdateForm) {
        checkRoleNameIsBlank(rolesUpdateForm.getRoleName());
        Integer id = rolesUpdateForm.getId();
        Roles roles = rolesService.getById(id);
        //如果更新的角色名称与数据库中的角色名称不相等  更新的角色名称不能冲突
        if (!roles.getRoleName().equals(rolesUpdateForm.getRoleName())) {
            checkRoleNameRepeat(roles.getRoleName());
        }
        BeanUtil.copyProperties(rolesUpdateForm, roles);
        return rolesService.updateById(roles);
    }

    private void checkRoleNameIsBlank(String roleName) {
        if (StrUtil.isBlank(roleName)) {
            throw new HttpException(ResultConstant.ROLE_NAME_IS_BLANK_ERROR);
        }
    }

    private void checkRoleNameRepeat(String roleName) {
        LambdaQueryWrapper<Roles> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Roles::getRoleName, roleName);
        int count = rolesService.count(queryWrapper);
        if (count > 0) {
            throw new HttpException(ResultConstant.ROLE_NAME_REPEAT_ERROR);
        }
    }

    @DeleteMapping("/delete/{roleId}")
    @ApiOperation("删除角色信息")
    public boolean delete(@PathVariable int roleId) {
        return rolesService.deleteById(roleId);
    }


    @GetMapping("/detail/{id}")
    @ApiOperation(value = "查看角色详细信息")
    public Roles detail(@PathVariable("id") int id) {
        return rolesService.getById(id);
    }


    @GetMapping("/all/menus/{roleId}")
    @ApiOperation(value = "根据角色ID查询角色拥有的菜单以及所有的菜单信息")
    public Map<String, List<Menus>> getAllMenuListAndRoleMenuList(@PathVariable int roleId) {
        //获得系统中的所有菜单信息
        List<Menus> allMenus = menusService.getAllMenus(new HashMap<>());
        //根据传入的角色ID查询角色对应的菜单信息
        List<Menus> roleMenus = menusService.getRoleMenus(roleId);
        List<Menus> resultMenus = CollUtil.newArrayList(roleMenus);
        //角色拥有的菜单既有父菜单也有子菜单。在树形结构中,一旦有父菜单ID,父菜单下的子菜单都会被选中。
        //所以要剔除掉角色对应的菜单中 父菜单的信息,只返回子菜单。
        // （树形组件 如果父菜单中的某个子菜单被选中父菜单就时半选中状态  如果父菜单中的所有子菜单被选中,父菜单也会被选中）
        // 问题转换成:
        // 遍历所有的角色菜单 如果A菜单的父菜单ID等于B菜单的ID,说明B菜单就是A菜单的父菜单,从集合中将B菜单删除即可。
        roleMenus.forEach(item -> {
            resultMenus.removeIf(item1 -> {
                return item1.getId().equals(item.getParentId());
            });
        });
        Map<String, List<Menus>> map = new HashMap<>();
        map.put("allMenus", allMenus);
        map.put("roleMenus", resultMenus);

        return map;
    }

    @PostMapping("/menus/update")
    @ApiOperation("更新角色对应的菜单")
    public boolean updateRoleMenu(@RequestBody Map<String, Object> params) {
        return menusService.updateRoleMenu(params);
    }
}
